import React from 'react';
import { Button, Field, Form, Input, Loading, Balloon, Message } from '@teamix/ui';
import { YunxiaoIcon, ButtonIcon } from '@alife/devops-ui';
import PasswordCheckPanel from './passwordCheckPanel';
import { tools } from 'components/PersonalSettings/components/utils/utils';
import {
  getUserHttpsAccount,
  modifyUserHttpsUsername,
  setHttpsCloneSecret,
  resetHttpsCloneSecret,
  sendResetHttpsCloneSecretToken,
  verifyUsername,
} from 'components/PersonalSettings/components/utils/api/index';
import './index.scss';
import intl from 'components/PersonalSettings/components/locale';

const prefix = 'https-clone-account';
const FormItem = Form.Item;

const SECRET_MIN_LENGTH = 8;
const SECRET_MAX_LENGTH = 100;
const SECRET_MIN_LETTERS = 1;
const SECRET_MIN_DIGITS = 1;
const SECRET_MIN_SPECIAL_CHARS = 1;

export default class HttpsCloneAccount extends React.Component {
  constructor(props) {
    super(props);
    this.changeUsernameField = new Field(this);
    this.setHttpsCloneSecretField = new Field(this);
    this.resetHttpsCloneSecretField = new Field(this);

    this.state = {
      httpsCloneUsername: null,
      userEmail: null,
      // 有三种状态：
      // 1. normal 正常; 2. no_https_secret 还未设置https公钥; 3. normal_but_no_binding_email 正常状态但是没有绑定邮箱
      httpsAccountStatus: null,

      submitting: false,
      submitingSetHttpsSecret: false,
      submitingResetHttpsSecret: false,

      changeHttpsCloneUsername: false,
      resetPasswordModalOpen: false,

      sendTokenBtnDisabled: false,
      sendTokenBtnDisabledTime: 60,
    };
  }

  componentDidMount() {
    // 获取账户信息
    getUserHttpsAccount()
      .then((result) => {
        if (result === null) {
          return;
        }
        this.updateAccountInfo(result.https_clone_username, result.email, result.account_type);
      })
      .catch((err) => {
        console.error(err);
        this.toastErrorFromApi(err);
      });
  }

  updateAccountInfo = (username, email, accountStatus) => {
    this.setState({
      httpsCloneUsername: username,
      userEmail: email,
      httpsAccountStatus: accountStatus,
    });
  };

  checkHttpsCloneUsername = (value, callback) => {
    // 调用后端接口查询username是否重复
    verifyUsername(value)
      .then(() => {
        callback();
      })
      .catch((err) => {
        const errCause = err.data.cause;
        if (!errCause) {
          callback();
        } else {
          callback(`${errCause}`);
        }
      });
  };

  cloneUsernameValidator = (rule, value, callback) => {
    if (value.length > 255) {
      callback(intl.get('username_length_cannot_gt'));
      return;
    }

    // 字母数字下划线
    if (!/^[\w.-]+$/.test(value)) {
      callback(intl.get('username_only_support_alphanumeric_underscore'));
      return;
    }

    this.checkHttpsCloneUsername(value, callback);
  };

  saveChanges = () => {
    if (this.state.submitting) {
      return;
    }
    this.setState({
      submitting: true,
    });
    this.changeUsernameField.validate((errors) => {
      if (!errors) {
        const formData = this.changeUsernameField.getValues();
        const newUsername = formData.new_https_clone_username;
        modifyUserHttpsUsername(newUsername)
          .then((result) => {
            // if (!result.success) {
            //   this.toastError(intl.get('modify_username_failed'));
            // } else {
            this.toastSuccess(intl.get('modify_success'));
            this.updateAccountInfo(result.https_clone_username, result.email, result.account_type);
            // }

            this.setState({
              submitting: false,
              changeHttpsCloneUsername: false,
            });
          })
          .catch((err) => {
            console.error(err);
            this.setState({
              submitting: false,
              changeHttpsCloneUsername: false,
            });
            this.toastErrorFromApi(err);
          });
      } else {
        this.setState({
          submitting: false,
        });
      }
    });
  };

  toastErrorFromApi(err) {
    let errorInfo = '';
    try {
      const responseText = JSON.parse(err.responseText);
      errorInfo = responseText.message || responseText.errorCode;
    } catch (e) {
      errorInfo = intl.get({
        id: 'code-assets.components.commitDetail.TheSystemIsBusyPlease',
        defaultMessage: '系统繁忙，请稍后重试',
      });
    }

    Message.error({
      title: errorInfo,
    });
  }

  toastSuccess(msg) {
    window.FORCE.user.isSaved = true;
    Message.success({
      title: msg,
    });
  }

  toastError(msg) {
    Message.error({
      title: msg,
    });
  }
  renderChangeCloneUsername = () => {
    const { submitting, httpsCloneUsername } = this.state;
    const { init } = this.changeUsernameField;
    const hasError = this.changeUsernameField.getError('new_https_clone_username');
    const inputValue = this.changeUsernameField.getValue('new_https_clone_username');
    const usernameInputEmpty = inputValue === undefined || inputValue === null;
    const isUnchanged =
      (inputValue && inputValue.toUpperCase()) ===
      (httpsCloneUsername && httpsCloneUsername.toUpperCase());
    if (!window.FORCE.user.isSaved && isUnchanged) {
      Message.warning('账号未变更（不区分大小写），请重新输入');
    }
    window.FORCE.user.isSaved = false;
    return (
      <div>
        <Form field={this.changeUsernameField}>
          <FormItem required>
            <Input
              style={{ width: 320 }}
              placeholder={intl.get('please_input_new_username')}
              maxLength={255}
              {...init('new_https_clone_username', {
                initValue: httpsCloneUsername,
                rules: [
                  {
                    required: true,
                    message: intl.get('item_necessary'),
                  },
                  {
                    validator: isUnchanged ? this.cloneUsernameValidator : null,
                  },
                ],
              })}
            />
          </FormItem>
          <FormItem>
            <Button
              type="primary"
              loading={submitting}
              onClick={this.saveChanges}
              disabled={hasError || usernameInputEmpty || isUnchanged}
            >
              {intl.get('save_username')}
            </Button>
          </FormItem>
        </Form>
      </div>
    );
  };

  renderCloneUsername = () => {
    const { httpsCloneUsername, changeHttpsCloneUsername } = this.state;
    return (
      <div className={`${prefix}-username`}>
        <div className={`${prefix}-username-title`}>{intl.get('clone_account')}</div>
        {changeHttpsCloneUsername ? (
          <React.Fragment>{this.renderChangeCloneUsername()}</React.Fragment>
        ) : (
          <div className={`${prefix}-username-content`}>
            <span>{httpsCloneUsername}</span>
            <ButtonIcon
              className={`${prefix}-username-content-button`}
              name="edit-line"
              type="primary"
              onClick={() => {
                this.setState(() => {
                  return {
                    changeHttpsCloneUsername: true,
                  };
                });
              }}
            />
          </div>
        )}
      </div>
    );
  };

  confirmHttpsCloneSecretValidator = (rule, value, callback) => {
    const firstInputSecret = this.setHttpsCloneSecretField.getValue('https_clone_secret');
    if (value !== firstInputSecret) {
      callback(intl.get('twice_input_password_not_same'));
      return;
    }
    callback();
  };

  confirmResetHttpsCloneSecretValidator = (rule, value, callback) => {
    const firstInputSecret = this.resetHttpsCloneSecretField.getValue('reset_https_clone_secret');
    if (value !== firstInputSecret) {
      callback(intl.get('twice_input_password_not_same'));
      return;
    }
    callback();
  };

  resetHttpsCloneSecretValidator = (rule, value, callback) => {
    const confirmSecret = this.resetHttpsCloneSecretField.getValue(
      'confirm_reset_https_clone_secret',
    );
    if (value !== confirmSecret && confirmSecret) {
      callback(intl.get('twice_input_password_not_same'));
      return;
    }
    callback();
  };

  httpsClonePasswordCheck = (rule, value, callback) => {
    const httpsClonePassword = this.setHttpsCloneSecretField.getValue('https_clone_secret');
    if (!tools.checkIsLegalCharaters(httpsClonePassword)) {
      callback(intl.get('password_contain_illegal_special_charaters'));
      return;
    }
    if (!this.checkPasswordValid(httpsClonePassword)) {
      callback(intl.get('password_not_valid'));
      return;
    }
    callback();
  };

  resetHttpsClonePasswordCheck = (rule, value, callback) => {
    const resetHttpsClonePassword = this.resetHttpsCloneSecretField.getValue(
      'reset_https_clone_secret',
    );
    if (!tools.checkIsLegalCharaters(resetHttpsClonePassword)) {
      callback(intl.get('password_contain_illegal_special_charaters'));
      return;
    }
    if (!this.checkPasswordValid(resetHttpsClonePassword)) {
      callback(intl.get('password_not_valid'));
      return;
    }
    callback();
  };

  setHttpsCloneSecret = () => {
    if (this.state.submitingSetHttpsSecret) {
      return;
    }
    this.setState({
      submitingSetHttpsSecret: true,
    });
    this.setHttpsCloneSecretField.validate((errors) => {
      if (!errors) {
        // 校验密码格式
        if (
          !tools.checkIsLegalCharaters(this.setHttpsCloneSecretField.getValue('https_clone_secret'))
        ) {
          return;
        }
        if (
          !this.checkPasswordValid(this.setHttpsCloneSecretField.getValue('https_clone_secret'))
        ) {
          return;
        }

        const formData = this.setHttpsCloneSecretField.getValues();
        const username = this.state.httpsCloneUsername;
        const cloneSecret = formData.https_clone_secret;

        setHttpsCloneSecret(username, cloneSecret)
          .then((result) => {
            this.toastSuccess(intl.get('setting_success'));
            this.setState({
              submitingSetHttpsSecret: false,
              changeHttpsCloneUsername: false,
            });
            this.updateAccountInfo(result.https_clone_username, result.email, result.account_type);
          })
          .catch((err) => {
            console.error(err);
            this.toastErrorFromApi(err);
            this.setState({
              submitingSetHttpsSecret: false,
            });
          });
        // Message提示
      } else {
        this.setState({
          submitingSetHttpsSecret: false,
        });
      }
    });
  };

  resetHttpsCloneSecret = () => {
    if (this.state.submitingResetHttpsSecret) {
      return;
    }

    this.setState({
      submitingResetHttpsSecret: true,
    });

    this.resetHttpsCloneSecretField.validate((errors) => {
      if (!errors) {
        // 校验密码格式
        if (
          !this.checkPasswordValid(
            this.resetHttpsCloneSecretField.getValue('reset_https_clone_secret'),
          )
        ) {
          return;
        }

        const formData = this.resetHttpsCloneSecretField.getValues();
        const username = this.state.httpsCloneUsername;
        const secret = formData.reset_https_clone_secret;
        const resetToken = formData.reset_https_clone_secret_token;

        // 重置密码
        resetHttpsCloneSecret(username, secret, resetToken)
          .then((res) => {
            // const { result } = res;
            // if (res.success) {
            this.toastSuccess(intl.get('reset_password_success'));
            this.updateAccountInfo(res.https_clone_username, res.email, res.account_type);
            this.setState({
              resetPasswordModalOpen: false,
              submitingResetHttpsSecret: false,
            });
            // } else {
            //   this.setState({
            //     submitingResetHttpsSecret: false,
            //   });
            //   Message.error(result.message);
            // }
          })
          .catch((err) => {
            this.toastErrorFromApi(err);
            console.error(err);
            this.setState({
              submitingResetHttpsSecret: false,
            });
          });
      } else {
        this.setState({
          submitingResetHttpsSecret: false,
        });
      }
    });
  };

  // 克隆公钥格式检查
  checkPasswordValid = (httpsCloneSecret) => {
    if (!httpsCloneSecret) {
      return false;
    }

    // 1. 长度
    const checkMinLength = tools.checkPasswordMinLength(httpsCloneSecret, SECRET_MIN_LENGTH);
    const checkMaxLength = tools.checkPasswordMaxLength(httpsCloneSecret, SECRET_MAX_LENGTH);

    // 2. 字母
    const checkLetters = tools.checkMinLetters(httpsCloneSecret, SECRET_MIN_LETTERS);

    // 3. 数字
    const checkDigits = tools.checkMinDigits(httpsCloneSecret, SECRET_MIN_DIGITS);

    // 4. 特殊字符
    const checkSpecialChars = tools.checkMinSpecialCharacters(
      httpsCloneSecret,
      SECRET_MIN_SPECIAL_CHARS,
    );

    return checkMinLength && checkMaxLength && (checkLetters || checkSpecialChars) && checkDigits;
  };

  sendResetToken = () => {
    this.setState({
      sendTokenBtnDisabled: true,
    });
    this.btnInterval = setInterval(() => {
      const { sendTokenBtnDisabledTime } = this.state;
      if (sendTokenBtnDisabledTime <= 0) {
        window.clearInterval(this.btnInterval);
        this.setState({
          sendTokenBtnDisabled: false,
          sendTokenBtnDisabledTime: 60,
        });
      } else {
        const count = sendTokenBtnDisabledTime - 1;
        this.setState({
          sendTokenBtnDisabledTime: count,
        });
      }
    }, 1000);
    sendResetHttpsCloneSecretToken()
      .then(() => {
        this.toastSuccess(intl.get('send_verification_code_success'));
      })
      .catch((err) => {
        console.error(err);
        this.toastErrorFromApi(err);
      });
  };

  renderNoHttpsSecret = () => {
    const { submitingSetHttpsSecret } = this.state;
    const { init } = this.setHttpsCloneSecretField;
    const httpsCloneSecret = this.setHttpsCloneSecretField.getValue('https_clone_secret');
    const confirmHttpsCloneSecret = this.setHttpsCloneSecretField.getValue(
      'confirm_https_clone_secret',
    );

    const disableSave =
      this.setHttpsCloneSecretField.getError('confirm_https_clone_secret') ||
      this.setHttpsCloneSecretField.getError('https_clone_secret') ||
      !this.setHttpsCloneSecretField.getValue('confirm_https_clone_secret') ||
      !this.setHttpsCloneSecretField.getValue('https_clone_secret') ||
      !this.checkPasswordValid(httpsCloneSecret) ||
      httpsCloneSecret !== confirmHttpsCloneSecret;

    return (
      <div className={`${prefix}-set-secret`}>
        <div className={`${prefix}-set-secret-form`}>
          <div className={`${prefix}-set-secret-form-span`}>
            <YunxiaoIcon type="warning-fill" style={{ color: '#FA8C15' }} />
            <span style={{ marginLeft: 7 }}>{intl.get('not_set_https_clone_secret')}</span>
          </div>
          <div>
            <Form field={this.setHttpsCloneSecretField}>
              <FormItem required label={intl.get('https_clone_secret')}>
                <Input
                  style={{ width: 320 }}
                  htmlType="password"
                  placeholder={intl.get('please_input_https_clone_secret')}
                  maxLength={SECRET_MAX_LENGTH}
                  {...init(
                    'https_clone_secret',
                    {
                      rules: [
                        {
                          required: true,
                          message: intl.get('item_necessary'),
                        },
                        {
                          validator: this.httpsClonePasswordCheck,
                        },
                      ],
                    },
                    {
                      onChange: () => {
                        this.setHttpsCloneSecretField.validate();
                      },
                    },
                  )}
                />
              </FormItem>
              <FormItem required label={intl.get('confirm_password')}>
                <Input
                  style={{ width: 320 }}
                  htmlType="password"
                  placeholder={intl.get('please_input_https_clone_secret')}
                  maxLength={SECRET_MAX_LENGTH}
                  {...init('confirm_https_clone_secret', {
                    rules: [
                      {
                        required: true,
                        message: intl.get('item_necessary'),
                      },
                      {
                        validator: this.confirmHttpsCloneSecretValidator,
                      },
                    ],
                  })}
                />
              </FormItem>
              <FormItem>
                <Button
                  type="primary"
                  disabled={disableSave}
                  onClick={this.setHttpsCloneSecret}
                  loading={submitingSetHttpsSecret}
                >
                  {intl.get('save')}
                </Button>
              </FormItem>
            </Form>
          </div>
        </div>
        <div className={`${prefix}-password-check-panel`}>
          <PasswordCheckPanel
            password={httpsCloneSecret}
            passwordMinLength={8}
            passwordMaxLength={SECRET_MAX_LENGTH}
            minLetters={1}
            minDigits={1}
            minSpecialCharacters={1}
            setPasswordCheckResult={this.validPasswordFormat}
          />
        </div>
        <div style={{ clear: 'both' }} />
      </div>
    );
  };

  renderNormal = (httpsAccountStatus) => {
    return (
      <div style={{ display: 'inline-flex' }}>
        <span style={{ paddingTop: '3px' }}>************</span>
        {httpsAccountStatus === 'normal_but_no_binding_email' ? (
          <React.Fragment>
            <Button
              style={{ marginLeft: 15 }}
              type="primary"
              text
              onClick={() => {
                this.props.changeNavSelect(['personal-info']);
              }}
            >
              {intl.get('bind_email')}
            </Button>
            <span>{intl.get('can_modify_password')}</span>
          </React.Fragment>
        ) : (
          <Button
            style={{ marginLeft: 15 }}
            type="primary"
            text
            onClick={() => {
              this.setState({ resetPasswordModalOpen: true });
            }}
          >
            {intl.get('modify_password')}
          </Button>
        )}
      </div>
    );
  };

  renderResetHttpsCloneSecret = () => {
    const { userEmail, sendTokenBtnDisabled, sendTokenBtnDisabledTime, submitingResetHttpsSecret } =
      this.state;
    const { init } = this.resetHttpsCloneSecretField;
    const httpsCloneSecret = this.resetHttpsCloneSecretField.getValue('reset_https_clone_secret');

    const disableSave =
      this.resetHttpsCloneSecretField.getError('confirm_reset_https_clone_secret') ||
      this.resetHttpsCloneSecretField.getError('reset_https_clone_secret') ||
      !this.resetHttpsCloneSecretField.getValue('confirm_reset_https_clone_secret') ||
      !this.resetHttpsCloneSecretField.getValue('reset_https_clone_secret') ||
      !this.checkPasswordValid(httpsCloneSecret);

    return (
      <div className={`${prefix}-reset-secret`}>
        <div className={`${prefix}-reset-secret-title`}>{intl.get('modify_clone_password')}</div>
        <div>
          <div className={`${prefix}-reset-secret-content`}>
            <Form
              field={this.resetHttpsCloneSecretField}
              className={`${prefix}-reset-secret-content-form`}
            >
              <FormItem
                className={`${prefix}-reset-secret-content-form-item`}
                label={
                  <React.Fragment>
                    {intl.get('email')}
                    <Balloon.Tooltip
                      align="t"
                      trigger={
                        <ButtonIcon
                          type="primary"
                          name="information-line"
                          style={{ marginLeft: 4, display: 'inline-block' }}
                        />
                      }
                    >
                      {intl.get('https_clone_email_description')}
                    </Balloon.Tooltip>
                  </React.Fragment>
                }
              >
                <Input disabled value={userEmail} />
              </FormItem>
              <FormItem
                className={`${prefix}-reset-secret-content-form-item`}
                label={intl.get('verification_code')}
                required
              >
                <Input
                  placeholder={intl.get('please_input_verification_code')}
                  className={`${prefix}-reset-secret-content-form-token-input`}
                  {...init('reset_https_clone_secret_token', {
                    rules: [
                      {
                        required: true,
                        message: intl.get('item_necessary'),
                      },
                    ],
                  })}
                />
                <Button
                  className={`${prefix}-reset-secret-content-form-token-btn`}
                  type="primary"
                  text
                  onClick={this.sendResetToken}
                  disabled={sendTokenBtnDisabled}
                >
                  {sendTokenBtnDisabled ? (
                    <span>
                      {`${intl.get(
                        'resend_verification_code_email',
                      )}（${sendTokenBtnDisabledTime}）`}
                    </span>
                  ) : (
                    <span>{intl.get('send_verification_code_email')}</span>
                  )}
                </Button>
              </FormItem>
              <FormItem
                className={`${prefix}-reset-secret-content-form-item`}
                label={intl.get('new_password')}
                required
              >
                <Input
                  style={{ width: 320 }}
                  htmlType="password"
                  placeholder={intl.get('please_input_new_https_clone_secret')}
                  maxLength={SECRET_MAX_LENGTH}
                  {...init(
                    'reset_https_clone_secret',
                    {
                      rules: [
                        {
                          required: true,
                          message: intl.get('item_necessary'),
                        },
                        {
                          validator: this.resetHttpsClonePasswordCheck,
                        },
                      ],
                    },
                    {
                      onChange: () => {
                        this.resetHttpsCloneSecretField.validate();
                      },
                    },
                  )}
                />
              </FormItem>
              <FormItem
                className={`${prefix}-reset-secret-content-form-item`}
                label="确认新密码"
                required
              >
                <Input
                  style={{ width: 320 }}
                  htmlType="password"
                  placeholder={intl.get('please_input_new_password_again')}
                  maxLength={SECRET_MAX_LENGTH}
                  {...init('confirm_reset_https_clone_secret', {
                    rules: [
                      {
                        validator: this.confirmResetHttpsCloneSecretValidator,
                      },
                    ],
                  })}
                />
              </FormItem>
              <FormItem>
                <Button
                  onClick={() => {
                    this.setState({ resetPasswordModalOpen: false });
                  }}
                >
                  {intl.get('cancel')}
                </Button>
                <Button
                  type="primary"
                  disabled={disableSave}
                  onClick={this.resetHttpsCloneSecret}
                  style={{ marginLeft: 12 }}
                  loading={submitingResetHttpsSecret}
                >
                  {intl.get('save')}
                </Button>
              </FormItem>
            </Form>
          </div>
          <div className={`${prefix}-password-check-panel`}>
            <PasswordCheckPanel
              password={httpsCloneSecret}
              passwordMinLength={8}
              passwordMaxLength={SECRET_MAX_LENGTH}
              minLetters={1}
              minDigits={1}
              minSpecialCharacters={1}
              setPasswordCheckResult={this.validPasswordFormat}
              lang={this.props.uiless_config ? this.props.uiless_config.lang : 'zh_cn'}
            />
          </div>
          <div style={{ clear: 'both' }} />
        </div>
      </div>
    );
  };

  renderCloneSecret = () => {
    const { httpsAccountStatus } = this.state;

    let httpsCloneSecretJsx;
    if (!httpsAccountStatus) {
      httpsCloneSecretJsx = (
        <Loading className="httpsPwLoading" style={{ textAlign: 'center', height: '100%' }} />
      );
    } else if (httpsAccountStatus === 'no_https_secret') {
      httpsCloneSecretJsx = this.renderNoHttpsSecret();
    } else {
      // normal, normal_but_no_binding_email
      httpsCloneSecretJsx = this.renderNormal(httpsAccountStatus);
    }

    return (
      <div className={`${prefix}-secret`}>
        <div className={`${prefix}-secret-title`}>{intl.get('clone_secret')}</div>
        <div className={`${prefix}-secret-content`}>{httpsCloneSecretJsx}</div>
      </div>
    );
  };

  render() {
    const { httpsCloneUsername, httpsAccountStatus, resetPasswordModalOpen } = this.state;
    const loading = !httpsCloneUsername || !httpsAccountStatus;

    let secretJsx;
    if (resetPasswordModalOpen) {
      secretJsx = this.renderResetHttpsCloneSecret();
    } else {
      secretJsx = this.renderCloneSecret();
    }

    return (
      <div>
        {loading ? (
          <div className={`${prefix}-loading`}>
            <Loading />
          </div>
        ) : (
          <div className={`${prefix}-content`}>
            {this.renderCloneUsername()}
            {secretJsx}
          </div>
        )}
      </div>
    );
  }
}
